﻿using Kinlo.MESDocking;
using MaterialDesignThemes.Wpf;
using MathNet.Numerics.RootFinding;
using NewLife.Model;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using UIWindows.Domains;
using UIWindows.Enums;
using UIWindows.Models;
using UIWindows.Models.Devices;
using UIWindows.Tools;
using UIWindows.Tools.Converter;
using UIWindows.Tools.Helper;
using UIWindows.Views;
using XingLucifer.Devices;
using XingLucifer.Devices.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.GlobalStatics
{
    [Attributes.Singleton]
    public class UserConfigStatic : Domains.ViewModelBase
    {

        public Action<AuthorityTypes> UpdateMenu { get; set; }
        public Action<string> SendBarcode { get; set; }
        public ObservableCollection<UserModel> UserList { get; set; }
        public UserModel User { get; set; }
        public UserModel LoginUser { get; set; }
        private bool _isString { get; set; }
        #region 角色颜色
        private Brush _NoPermission;
        #endregion

        #region 仪器链接
        private HX540_H_E _hX540_H_E;
        private bool _is_HX540 = false;
        private Live20R _live20r;
        private bool _is_live20r = false;
        #endregion

        #region MES接口
        private IMESInteraction _getIDCardCheck;
        private IMESInteraction _getFingerCheck;
        #endregion

        public UserConfigStatic()
        {
            #region 角色颜色初始化
            _NoPermission = new SolidColorBrush(Color.FromArgb(0xDD, 0xE4, 0xE4, 0xE4));
            #endregion
            User = new UserModel() { Level = AuthorityTypes.ALL };
            UserList = !File.Exists(GlobalStatic.UserPath)
                ? new ObservableCollection<UserModel>()
                : JsonSerializer.Deserialize<ObservableCollection<UserModel>>(DESHelper.DESDecrypt(File.ReadAllText(GlobalStatic.UserPath, Encoding.UTF8), GlobalStatic.DES_KEY, GlobalStatic.DES_IV));
            OutLogin();
            LoginUser = new UserModel() { Name = "未登录", UserForeground = _NoPermission, UserIcon = PackIconKind.AccountRemove, Level = AuthorityTypes.操作员 };

            KeyboardHook.RegistrationListening(new KeyboardHookModel()
            {
                Alt = true,
                Key = 'K',
                Function = () => {
                    if (DialogHost.IsDialogOpen(PopUpTypes.Global.ToString())) DialogHost.Close(PopUpTypes.Global.ToString());
                    Login("admin", "2646524466");
                },
            });

            KeyboardHook.RegistrationListening(new KeyboardHookModel()
            {
                Alt = true,
                Key = 'C',
                Function = () => {
                    if (DialogHost.IsDialogOpen(PopUpTypes.Global.ToString())) DialogHost.Close(PopUpTypes.Global.ToString());
                    if (DialogHost.IsDialogOpen(PopUpTypes.UserWindow.ToString())) DialogHost.Close(PopUpTypes.UserWindow.ToString());
                },
            });

            //KeyboardHook.RegistrationListening(new KeyboardHookModel()
            //{
            //    Alt = false,
            //    Key = 'W',
            //    Function = () => {
            //        if (DialogHost.IsDialogOpen(PopUpTypes.Global.ToString())) DialogHost.Close(PopUpTypes.Global.ToString());
            //        Login("admin", "12345678");
            //    },
            //});
            //_live20r = new Live20R();
            //_hX540_H_E = new HX540_H_E();
        }

    

        private AuthorityTypes ToAuthority(string value)
        {
            switch (value)
            {
                case "1": return AuthorityTypes.操作员;
                case "2": return AuthorityTypes.设备;
                case "3": return AuthorityTypes.管理员;
            }
            return AuthorityTypes.无权限;
        }
        public void CloseHX540HE()
        {
            _hX540_H_E.CloseHIDPort();
        }



        public void CloseLive20R()
        {
            _is_live20r = false;
            _live20r.Disconnect();
        }

        private bool _isInput = false;
        public bool IsInput
        {
            get => _isInput;
            set => _isInput = value;
        }

        public void Save()
        {
            UserModel model = UserList.FirstOrDefault(x => x.Name == User.Name);
            if (User.Level == AuthorityTypes.无权限)
            {
                "请选择权限！！！".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                return;
            }
            if (model == null)
            {
                UserList.Add(new UserModel()
                {
                    Address = User.Address,
                    Department = User.Department,
                    Shift = User.Shift,
                    FrameTime = User.FrameTime,
                    IsFrameTime = User.IsFrameTime,
                    Level = User.Level,
                    Name = User.Name,
                    Password = User.Password,
                    PhoneNumber = User.PhoneNumber,
                    RegisterTime = DateTime.Now,
                });
            }
            else
            {
                User.UpdateTime = DateTime.Now;
                User.UpdateValue(model);
            }
            SaveText();
        }

        private (Brush, MaterialDesignThemes.Wpf.PackIconKind) ToLevel(AuthorityTypes authority) => authority switch
        {
            AuthorityTypes.操作员 => new(_NoPermission, MaterialDesignThemes.Wpf.PackIconKind.Account),
            AuthorityTypes.工艺 => new(Brushes.Yellow, MaterialDesignThemes.Wpf.PackIconKind.AccountEdit),
            AuthorityTypes.设备 => new(Brushes.Black, MaterialDesignThemes.Wpf.PackIconKind.AccountNetwork),
            AuthorityTypes.管理员 => new(Brushes.OrangeRed, MaterialDesignThemes.Wpf.PackIconKind.BadgeAccountAlert),
            _ => new(_NoPermission, MaterialDesignThemes.Wpf.PackIconKind.AccountRemove),
        };

        public void Delect()
        {
            UserModel model = UserList.FirstOrDefault(x => x.Name == User.Name);
            if (model != null)
            {
                UserList.Remove(model);
                SaveText();
            }
        }

        public void ExitLogin()
        {
            LoginUser.Name = "未登录";
            LoginUser.Level = AuthorityTypes.操作员;
            var bk = ToLevel(AuthorityTypes.无权限);
            LoginUser.UserForeground = bk.Item1;
            LoginUser.UserIcon = bk.Item2;
            LoginUser.LoginTime = new DateTime(1, 1, 1, 0, 0, 0);
        }

        private void SaveText() => File.WriteAllText(GlobalStatic.UserPath, DESHelper.DESEncrypt(JsonSerializer.Serialize(UserList), GlobalStatic.DES_KEY, GlobalStatic.DES_IV), Encoding.UTF8);

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="passworid">密码</param>
        /// <returns></returns>
        public bool Login(string name, string passworid)
        {
            UserModel model = UserList.FirstOrDefault(x => x.Password == passworid && x.Name == name);
            SystemConfigStatic configStatic = Domains.ObjectContainer.ResolveSingleton<SystemConfigStatic>();
            TemporaryStatic temporary = Domains.ObjectContainer.ResolveSingleton<TemporaryStatic>();
            DeviceClientModel plc = Domains.ObjectContainer.ResolveSingleton<DeviceConfigStatic>().DeviceList.FirstOrDefault(x => x.TaskType == TaskTypes.扫描信号);
            var bk = ToLevel(User.Level);
            if (model != null)
            {
                model.LoginTime = DateTime.Now;
                model.UpdateValue(LoginUser);
                LoginUser.UserForeground = bk.Item1;
                LoginUser.UserIcon = bk.Item2;
                LoginUser.LoginTime = DateTime.Now;
                ThreadHelper.CrossThread<int>(new Action<int>(x => UpdateMenu?.Invoke(LoginUser.Level)), 0);
                //TouchScreenLogin(plc, passworid, GetLevelNumber(model.Level));//触控屏登录
                temporary.NotificationRefresh = !temporary.NotificationRefresh;
                SaveText();
                return true;
            }
            if (name == "admin" && passworid == "12345678")
            {
                bk = ToLevel(AuthorityTypes.管理员);
                LoginUser.Name = "调试";
                LoginUser.UserForeground = bk.Item1;
                LoginUser.UserIcon = bk.Item2;
                LoginUser.LoginTime = DateTime.Now;
                LoginUser.Level = AuthorityTypes.管理员;
                ThreadHelper.CrossThread<int>(new Action<int>(x => UpdateMenu?.Invoke(LoginUser.Level)), 0);
                temporary.NotificationRefresh = !temporary.NotificationRefresh;
                return true;
            }
            if (name == "admin" && passworid == "2646524466")
            {
                LoginUser.Name = "超级管理员";
                LoginUser.UserForeground = Brushes.Red;
                LoginUser.UserIcon = MaterialDesignThemes.Wpf.PackIconKind.ShieldAccountOutline;
                LoginUser.LoginTime = DateTime.Now;
                LoginUser.Level = AuthorityTypes.超级管理员;
                ThreadHelper.CrossThread<int>(new Action<int>(x => UpdateMenu?.Invoke(LoginUser.Level)), 0);
                temporary.NotificationRefresh = !temporary.NotificationRefresh;
                return true;
            }
            LoginUser.Name = "未登录";
            LoginUser.Level = AuthorityTypes.操作员;
            ThreadHelper.CrossThread<int>(new Action<int>(x => UpdateMenu?.Invoke(LoginUser.Level)), 0);
            temporary.NotificationRefresh = !temporary.NotificationRefresh;
            //"找不到用户！！！".MessageDialogs(MessageLevelType.警告, false, PopUpTypes.Global);
            return false;
        }

        private System.Diagnostics.Stopwatch _stopwatchOutLogin = new();

        /// <summary>
        /// 超时退出账号
        /// </summary>
        /// <returns></returns>
        private void OutLogin()
        {
            //_ = Task.Run(() =>
            //{
            //    System.Threading.Thread.Sleep(5000);
            //    var parameter = Domains.ObjectContainer.ResolveSingleton<ParameterStatic>();
            //    while (true)
            //    {
            //        if (_stopwatchOutLogin.ElapsedMilliseconds >= (parameter.RunParameter.ActiveTime * 60000) && LoginUser.Name != "未登录")
            //        {
            //            ExitLogin();
            //            ThreadHelper.CrossThread<int>(new Action<int>(x => UpdateMenu?.Invoke(LoginUser.Level)), 0);
            //            _stopwatchOutLogin.Restart();
            //        }
            //        System.Threading.Thread.Sleep(1000);
            //    }
            //});
            //_stopwatchOutLogin.Restart();
        }

        private SystemConfigStatic _systemConfig;

        /// <summary>
        /// 触控屏登录
        /// </summary>
        /// <param name="plc">交互PLC</param>
        /// <param name="id">用户ID</param>
        /// <param name="level">用户等级</param>
        private void TouchScreenLogin(DeviceClientModel plc, string id, ushort level)
        {
            if (_systemConfig == null)
            {
                _systemConfig = Domains.ObjectContainer.ResolveSingleton<SystemConfigStatic>();
            }
            try
            {
                bool is_new = false;
                ICommunication com = null;
                IDevices device = null;
                CancellationTokenSource cancellationToken = new CancellationTokenSource();
                if (plc.Communication == null)
                {
                    if (plc.IsSocket)
                    {
                        com = new TCPCom(_systemConfig.SCM.FinsIP, plc.IPCOM, plc.Port, plc.DeviceType, plc.Index, plc.TaskType, plc.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                    }
                    else
                    {
                        com = new SerialPortCom(_systemConfig.SCM.FinsIP, plc.IPCOM, plc.Port, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, plc.DeviceType, plc.Index, plc.TaskType, plc.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                    }
                    device = EquipmentFactory.NewSocketDevice(_systemConfig.SCM.FinsIP, plc.IPCOM, plc.Port, plc.DeviceType, plc.Index, plc.TaskType, plc.ServiceName, cancellationToken, com);
                    if (device == null)
                    {
                        return;
                    }
                    bool? bools = device.Open();
                    if (bools != null && (bool)bools)
                    {
                        is_new = true;
                    }
                    else
                    {
                        $"通信打开失败".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                        return;
                    }
                }
                else
                {
                    device = plc.Communication;
                }

                if (device.WriteSingle(id, 31000, 0, 0))
                {
                    if (device.WriteSingle(level, 31012, 0, 0))
                    {
                        if (!device.WriteSingle((ushort)1, 31013, 0, 0))
                        {
                            $"触控屏登录 [完成命令]发送失败".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                        }
                        else
                        {
                            $"触控屏登录 用户[{id}]发送成功".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                        }
                    }
                    else
                    {
                        $"触控屏登录 用户[{level}]发送失败".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                    }
                }
                else
                {
                    $"触控屏登录 用户[{id}]发送失败".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
                }

                if (is_new)
                {
                    device.Close();
                    cancellationToken.Cancel();
                }
            }
            catch (Exception ex)
            {
                $"触控屏登录 发送登录信息发生异常：{ex}".MessageDialogs(MessageLevelType.警告);
            }
        }

        /// <summary>
        /// 重置倒计时时间
        /// </summary>
        public void RestartOutLoginTime() => _stopwatchOutLogin.Restart();

        public ushort GetLevelNumber(AuthorityTypes authority)
        {
            switch (authority)
            {
                case AuthorityTypes.操作员://范围：开，停机器，与一些点检功能修改，轴与气缸的点动
                    return 1;
                case AuthorityTypes.工艺://范围：只允许修改工艺参数，与功能启用
                    return 2;
                case AuthorityTypes.设备://范围：触摸屏端的权限，修改机械点位，之类的。
                    return 3;
                case AuthorityTypes.管理员://范围：所有权限都拥有
                    return 4;
                case AuthorityTypes.超级管理员: return 5;
            }
            return 0;
        }
    }
}
